package com.gonsin.gnews.annotations.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.gonsin.gnews.annotations.bean.ConfigValueBean;
import com.gonsin.gnews.annotations.configuration.ConfigViewModel;
import com.gonsin.gnews.annotations.services.IConfigService;
import com.gonsin.gnews.annotations.services.IConfigValueService;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.autoconfigure.web.embedded.NettyWebServerFactoryCustomizer;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GNewsContext {

    /**
     * 当多租户的情况下，每个租户构建不同的设置时使用。
     */
    private String edificeKey;

    private String platform;

    @JsonIgnore
    private IConfigValueService configValueService;

    @JsonIgnore
    private IConfigService configService;

    public GNewsContext(String edificeKey, String platform, IConfigValueService configValueService, IConfigService configService){
        this.edificeKey = edificeKey;
        this.platform = platform;
        this.configValueService = configValueService;
        this.configService = configService;
    }

    /**
     * 配置
     */
    public <T> T getConfiguration(){
        ConfigViewModel viewModel = this.configService.getConfig(platform);
        Class clazz = viewModel.getConfigClass();
        Object instance = createConfigInstance(clazz);


        // TODO 获取配置
        ConfigValueModel model = this.configValueService.getConfigValue(edificeKey, platform);
        if(model == null){
            return (T) instance;
        }
        copyInstance(model.getItems(), instance);
        return (T) instance;
    }

    private void copyInstance(List<ConfigValueModel.ConfigItemPo> items, Object instance) {
        if(CollectionUtils.isEmpty(items)){
            return;
        }
        Map<String, Object> map = new HashMap<>();
        for(ConfigValueModel.ConfigItemPo item : items){
            map.put(item.getFieldName(), item.getValue());
        }
        String json = new Gson().toJson(map);
        Object delegate = new Gson().fromJson(json, instance.getClass());
        BeanUtils.copyProperties(delegate, instance);
    }


    /**
     * 创建配置对象
     */
    private Object createConfigInstance(Class clazz) {
        Object configInstance = null;
        try {
            configInstance = clazz.getConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return configInstance;
    }


    /**
     * 获取租户主键
     */
    public String getEdificeKey() {
        return edificeKey;
    }


    /**
     * 获取当前平台
     */
    public String getPlatform() {
        return platform;
    }
}
